package com.slz3.business.module.wmsManagement.wmsPurchaseOrderSelf.steward;

import com.slz3.business.frame.enums.AuditFlag;
import com.slz3.business.frame.enums.UsingFlag;
import com.slz3.business.frame.exception.ServiceErrorException;
import com.slz3.business.frame.module.Services;
import com.slz3.business.frame.response.RR;
import com.slz3.business.frame.response.ResInfo;
import com.slz3.business.frame.steward.Steward;
import com.slz3.business.frame.util.UUIDUtils;
import com.slz3.business.frame.util.VE;
import com.slz3.business.module.goodsManagement.baseGoods.domain.BaseGoods;
import com.slz3.business.module.goodsManagement.gooBaseGoodsSpecification.domain.GooBaseGoodsSpecification;
import com.slz3.business.module.goodsManagement.gooGoods.domain.GooGoods;
import com.slz3.business.module.wmsManagement.wmsPurchaseOrderLine.domain.WmsPurchaseOrderLine;
import com.slz3.business.module.wmsManagement.wmsPurchaseOrderSelf.domain.WmsPurchaseOrderSelf;
import com.slz3.business.module.wmsManagement.wmsPurchaseOrderSelf.domain.WmsPurchaseOrderSelfEnum;
import com.slz3.business.module.wmsManagement.wmsPurchaseOrderSelf.domain.WmsPurchaseOrderSelfFactory;
import com.slz3.business.module.wmsManagement.wmsPurchaseOrderSelf.req.AddForm;
import com.slz3.business.module.wmsManagement.wmsPurchaseOrderSelf.req.AddFormLine;
import com.slz3.business.module.wmsManagement.wmsPurchaseOrderSelf.req.UpdateForm;
import com.slz3.business.module.wmsManagement.wmsWarehouseManage.domain.WmsWarehouseManage;
import org.springframework.data.domain.Page;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

import javax.swing.text.html.Option;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

public class WmsPurchaseOrderSelfResExecutor {

    protected Mono<ServerResponse> add(ServerRequest req, AddForm form) {
        // 1. 创建采购单UUID
        UUID wmsPurchaseOrderSelfUUID = UUIDUtils.generateUUID();

        // 2 校验和构建采购订单行信息
        List<WmsPurchaseOrderLine> wmsPurchaseOrderLines = buildWmsPurchaseOrderLine(wmsPurchaseOrderSelfUUID, form.getFormLines());

        // 3.构建订单信息
        WmsPurchaseOrderSelf wmsPurchaseOrderSelf = buildWmsPurchaseOrderSelf(wmsPurchaseOrderSelfUUID, form);

        // 4 保存数据
        Services.wmsPurchaseOrderLine.saveList(wmsPurchaseOrderLines);
        Services.wmsPurchaseOrderSelf.save(wmsPurchaseOrderSelf);

        return RR.success(req, ResInfo.builder().code(RR.SUCCESS).build());
    }


    /**
     * known: wmsPurchaseOrderSelfList is not null
     */
    protected Mono<ServerResponse> delete(ServerRequest req) {
        List<WmsPurchaseOrderSelf> wmsPurchaseOrderSelfList = RR.attribute(req, RR.RELAY_SAFE_VALID);
        if (VE.isNotEmpty(wmsPurchaseOrderSelfList)) {
            List<WmsPurchaseOrderSelf> wmsPurchaseOrderSelfListNew = Services.wmsPurchaseOrderSelf.delete(wmsPurchaseOrderSelfList);
            if (VE.isNotEmpty(wmsPurchaseOrderSelfListNew) && wmsPurchaseOrderSelfListNew.size() == wmsPurchaseOrderSelfList.size()) {
                return RR.success(req, ResInfo.builder().code(RR.SUCCESS).domains(wmsPurchaseOrderSelfListNew).build());
            } else {
                return RR.fail(req, ResInfo.builder().code(RR.EXECUTOR).theme("delete fail").build());
            }
        } else {
            return RR.fail(req, ResInfo.builder().code(RR.EXECUTOR).theme("cannot find entity").build());
        }
    }

    protected Mono<ServerResponse> modify(ServerRequest req, UpdateForm form) {
        // 1.查询订单
        Optional<WmsPurchaseOrderSelf> wmsPurchaseOrderSelfOptional = Services.wmsPurchaseOrderSelf.single(form.getUuid());
        if (!wmsPurchaseOrderSelfOptional.isPresent()) {
            throw new ServiceErrorException("采购订单不存在！");
        }
        WmsPurchaseOrderSelf orderSelf = wmsPurchaseOrderSelfOptional.get();
        // 修改主订单表数据
        WmsPurchaseOrderSelf wmsPurchaseOrderSelf = mereOrderSelfData(orderSelf, form);
        // 2  删除旧订单行数据  插入新的数据
        mereOrderLineAndInsertData(form);
        // 3 保存住订单数据
        Services.wmsPurchaseOrderSelf.save(wmsPurchaseOrderSelf);

        return RR.success(req, ResInfo.builder().code(RR.SUCCESS).build());
    }


    protected Mono<ServerResponse> list(ServerRequest req) {
        Page<WmsPurchaseOrderSelf> wmsPurchaseOrderSelfPage = Services.wmsPurchaseOrderSelf.page(req.queryParams());
        return RR.success(req, ResInfo.builder().code(RR.SUCCESS).theme("page").page(wmsPurchaseOrderSelfPage).build());
    }

    protected Mono<ServerResponse> info(ServerRequest req) {
        WmsPurchaseOrderSelf target = RR.attribute(req, RR.RELAY_SAFE_VALID);
        if (target != null) {
            return RR.success(req, ResInfo.builder().code(RR.SUCCESS).domain(target).build());
        } else {
            return RR.fail(req, ResInfo.builder().code(RR.EXECUTOR).theme("cannot find entity").build());
        }
    }

    protected Mono<ServerResponse> choice(ServerRequest req) {
        Page<WmsPurchaseOrderSelf> wmsPurchaseOrderSelfPage = Services.wmsPurchaseOrderSelf.page(req.queryParams());
        return RR.success(req, ResInfo.builder().code(RR.SUCCESS).theme("page").page(wmsPurchaseOrderSelfPage).build());
    }

    /**
     * known: wmsPurchaseOrderSelfList is not null
     */
    protected Mono<ServerResponse> auditSubmit(ServerRequest req) {
        List<WmsPurchaseOrderSelf> wmsPurchaseOrderSelfList = RR.attribute(req, RR.RELAY_SAFE_VALID);
        if (VE.isNotEmpty(wmsPurchaseOrderSelfList)) {
            wmsPurchaseOrderSelfList.stream().forEach(item -> {
                item.setSerAudit(AuditFlag.WAIT_AUDIT);
                WmsPurchaseOrderSelfFactory.initBaseFields(item);
            });
            List<WmsPurchaseOrderSelf> wmsPurchaseOrderSelfListNew = Services.wmsPurchaseOrderSelfTransactional.batchModify(wmsPurchaseOrderSelfList);
            if (VE.isNotEmpty(wmsPurchaseOrderSelfListNew) && wmsPurchaseOrderSelfListNew.size() == wmsPurchaseOrderSelfList.size()) {
                return RR.success(req, ResInfo.builder().code(RR.SUCCESS).domains(wmsPurchaseOrderSelfListNew).build());
            } else {
                return RR.fail(req, ResInfo.builder().code(RR.EXECUTOR).theme("auditSubmit fail").build());
            }
        } else {
            return RR.fail(req, ResInfo.builder().code(RR.EXECUTOR).theme("cannot find entity").build());
        }
    }

    /**
     * known: wmsPurchaseOrderSelfList is not null
     */
    protected Mono<ServerResponse> audit(ServerRequest req) {
        List<WmsPurchaseOrderSelf> wmsPurchaseOrderSelfList = RR.attribute(req, RR.RELAY_SAFE_VALID);
        if (VE.isNotEmpty(wmsPurchaseOrderSelfList)) {
            wmsPurchaseOrderSelfList.stream().forEach(item -> {
                item.setSerAudit(AuditFlag.APPROVED);
                WmsPurchaseOrderSelfFactory.initBaseFields(item);
            });
            List<WmsPurchaseOrderSelf> wmsPurchaseOrderSelfListNew = Services.wmsPurchaseOrderSelfTransactional.batchModify(wmsPurchaseOrderSelfList);
            if (VE.isNotEmpty(wmsPurchaseOrderSelfListNew) && wmsPurchaseOrderSelfListNew.size() == wmsPurchaseOrderSelfList.size()) {
                return RR.success(req, ResInfo.builder().code(RR.SUCCESS).domains(wmsPurchaseOrderSelfListNew).build());
            } else {
                return RR.fail(req, ResInfo.builder().code(RR.EXECUTOR).theme("audit fail").build());
            }
        } else {
            return RR.fail(req, ResInfo.builder().code(RR.EXECUTOR).theme("cannot find entity").build());
        }
    }

    /**
     * known: wmsPurchaseOrderSelfList is not null
     */
    protected Mono<ServerResponse> auditReject(ServerRequest req) {
        List<WmsPurchaseOrderSelf> wmsPurchaseOrderSelfList = RR.attribute(req, RR.RELAY_SAFE_VALID);
        if (VE.isNotEmpty(wmsPurchaseOrderSelfList)) {
            wmsPurchaseOrderSelfList.stream().forEach(item -> {
                item.setSerAudit(AuditFlag.REJECT);
                WmsPurchaseOrderSelfFactory.initBaseFields(item);
            });
            List<WmsPurchaseOrderSelf> wmsPurchaseOrderSelfListNew = Services.wmsPurchaseOrderSelfTransactional.batchModify(wmsPurchaseOrderSelfList);
            if (VE.isNotEmpty(wmsPurchaseOrderSelfListNew) && wmsPurchaseOrderSelfListNew.size() == wmsPurchaseOrderSelfList.size()) {
                return RR.success(req, ResInfo.builder().code(RR.SUCCESS).domains(wmsPurchaseOrderSelfListNew).build());
            } else {
                return RR.fail(req, ResInfo.builder().code(RR.EXECUTOR).theme("auditReject fail").build());
            }
        } else {
            return RR.fail(req, ResInfo.builder().code(RR.EXECUTOR).theme("cannot find entity").build());
        }
    }

    /**
     * known: wmsPurchaseOrderSelfList is not null
     */
    protected Mono<ServerResponse> usingEnable(ServerRequest req) {
        List<WmsPurchaseOrderSelf> wmsPurchaseOrderSelfList = RR.attribute(req, RR.RELAY_SAFE_VALID);
        if (VE.isNotEmpty(wmsPurchaseOrderSelfList)) {
            wmsPurchaseOrderSelfList.stream().forEach(item -> {
                item.setSerUsing(UsingFlag.ENABLE);
                WmsPurchaseOrderSelfFactory.initBaseFields(item);
            });
            List<WmsPurchaseOrderSelf> wmsPurchaseOrderSelfListNew = Services.wmsPurchaseOrderSelfTransactional.batchModify(wmsPurchaseOrderSelfList);
            if (VE.isNotEmpty(wmsPurchaseOrderSelfListNew) && wmsPurchaseOrderSelfListNew.size() == wmsPurchaseOrderSelfList.size()) {
                return RR.success(req, ResInfo.builder().code(RR.SUCCESS).domains(wmsPurchaseOrderSelfListNew).build());
            } else {
                return RR.fail(req, ResInfo.builder().code(RR.EXECUTOR).theme("auditReject fail").build());
            }
        } else {
            return RR.fail(req, ResInfo.builder().code(RR.EXECUTOR).theme("cannot find entity").build());
        }
    }


    /**
     * known: wmsPurchaseOrderSelfList is not null
     */
    protected Mono<ServerResponse> usingDisable(ServerRequest req) {
        List<WmsPurchaseOrderSelf> wmsPurchaseOrderSelfList = RR.attribute(req, RR.RELAY_SAFE_VALID);
        if (VE.isNotEmpty(wmsPurchaseOrderSelfList)) {
            wmsPurchaseOrderSelfList.stream().forEach(item -> {
                item.setSerUsing(UsingFlag.DISABLE);
                WmsPurchaseOrderSelfFactory.initBaseFields(item);
            });
            List<WmsPurchaseOrderSelf> wmsPurchaseOrderSelfListNew = Services.wmsPurchaseOrderSelfTransactional.batchModify(wmsPurchaseOrderSelfList);
            if (VE.isNotEmpty(wmsPurchaseOrderSelfListNew) && wmsPurchaseOrderSelfListNew.size() == wmsPurchaseOrderSelfList.size()) {
                return RR.success(req, ResInfo.builder().code(RR.SUCCESS).domains(wmsPurchaseOrderSelfListNew).build());
            } else {
                return RR.fail(req, ResInfo.builder().code(RR.EXECUTOR).theme("usingDisable fail").build());
            }
        } else {
            return RR.fail(req, ResInfo.builder().code(RR.EXECUTOR).theme("cannot find entity").build());
        }
    }

    /**
     * 保存采购单采购校验
     *
     * @return
     */
    private List<GooGoods> checkDataForm(List<AddFormLine> formLines) {
        // 1 校验商品信息
        List<GooGoods> purchaseOrderLines = new ArrayList<>();
        // 2 判断商品是否存在
        formLines.stream().forEach(formLine -> {
            // 1 判断商品是否存在
            Optional<GooGoods> wmsPurchaseOrderLineOptional = Services.gooGoods.single(formLine.getGoodsUUID());
            if (!wmsPurchaseOrderLineOptional.isPresent()) {
                throw new ServiceErrorException("商品不存在");
            }
            // 2 判断商品规格是否存在
            Services.gooBaseGoodsSpecification.single(formLine.getGoodsSpecificationUUID());

            purchaseOrderLines.add(wmsPurchaseOrderLineOptional.get());
        });
        return purchaseOrderLines;
    }

    /**
     * 构建采购单行信息
     *
     * @param wmsPurchaseOrderSelfUUID 采购订单主表ID
     * @param formLines                采购订单行信息
     * @return 采购订单行集合
     */
    private List<WmsPurchaseOrderLine> buildWmsPurchaseOrderLine(UUID wmsPurchaseOrderSelfUUID, List<AddFormLine> formLines) {
        // 1 校验商品信息
        List<WmsPurchaseOrderLine> purchaseOrderLines = new ArrayList<>();
        // 2 判断商品是否存在
        formLines.stream().forEach(formLine -> {
            // 1 判断商品是否存在
            Optional<BaseGoods> wmsPurchaseOrderLineOptional = Services.baseGoods.single(formLine.getGoodsUUID());
            if (!wmsPurchaseOrderLineOptional.isPresent()) {
                throw new ServiceErrorException("商品不存在");
            }
            // 2 判断商品规格是否存在
            Optional<GooBaseGoodsSpecification> gooBaseGoodsSpecificationOptional = Services.gooBaseGoodsSpecification.single(formLine.getGoodsSpecificationUUID());
            if (!gooBaseGoodsSpecificationOptional.isPresent()) {
                throw new ServiceErrorException("商品规格不存在");
            }
            BaseGoods gooGoods = wmsPurchaseOrderLineOptional.get();
            GooBaseGoodsSpecification goodsSpecification = gooBaseGoodsSpecificationOptional.get();
            // 创建采购订单行信息
            WmsPurchaseOrderLine wmsPurchaseOrderLine = new WmsPurchaseOrderLine();
            // 生成采购订单行id
            wmsPurchaseOrderLine.setUuid(UUIDUtils.generateUUID());
            // 创建时间
            wmsPurchaseOrderLine.setCreateTime(LocalDateTime.now());
            // 主订单ID
            wmsPurchaseOrderLine.setWmsPurchaseOrderSelfUUID(wmsPurchaseOrderSelfUUID);
            // 商品ID
            wmsPurchaseOrderLine.setGoodsUUID(gooGoods.getUuid());
            // 商品名称
            wmsPurchaseOrderLine.setGoodsName(gooGoods.getSerGoodsName());
            // 商品编号
            wmsPurchaseOrderLine.setGoodsSerNum(gooGoods.getSerNum());
            // 商品规格
            wmsPurchaseOrderLine.setGoodsSpecificationUUID(goodsSpecification.getUuid());
            // 商品规格名称
            wmsPurchaseOrderLine.setGoodsSpecificationName(goodsSpecification.getSerName());
            // 单价
            wmsPurchaseOrderLine.setSinglePrice(formLine.getSinglePrice());
            // 总价
            wmsPurchaseOrderLine.setTotalPrice(formLine.getTotalPrice());
            // 采购数量
            wmsPurchaseOrderLine.setGoodsNum(formLine.getGoodsNum());
            // ......

            purchaseOrderLines.add(wmsPurchaseOrderLine);
        });
        return purchaseOrderLines;
    }

    /**
     * 构建订单信息
     *
     * @param wmsPurchaseOrderSelfUUID
     * @param form
     * @return
     */
    private WmsPurchaseOrderSelf buildWmsPurchaseOrderSelf(UUID wmsPurchaseOrderSelfUUID, AddForm form) {
        // 1 校验仓库是否存在
        Optional<WmsWarehouseManage> wmsWarehouseManageOptional = Services.wmsWarehouseManage.single(form.getWmsHorseId());
        if (!wmsWarehouseManageOptional.isPresent()) {
            throw new ServiceErrorException("仓库不存在！");
        }
        WmsWarehouseManage wmsWarehouseManage = wmsWarehouseManageOptional.get();

        // 2 封装采购订单信息
        WmsPurchaseOrderSelf wmsPurchaseOrderSelf = new WmsPurchaseOrderSelf();
        // uuid
        wmsPurchaseOrderSelf.setUuid(wmsPurchaseOrderSelfUUID);
        // 创建时间
        wmsPurchaseOrderSelf.setCreateTime(LocalDateTime.now());
        // 设置采购单号
        wmsPurchaseOrderSelf.setPurchaseOrderNo(WmsPurchaseBusinessUtil.generatePurchaseOrderNo());
        // 采购订单状态 -- 默认 编辑中
        WmsPurchaseOrderSelfEnum.WmsOrderStatus status = WmsPurchaseOrderSelfEnum.WmsOrderStatus.BIAN_JI;
        // 判断是否直接入库
        if (WmsPurchaseOrderSelfEnum.WmsOrderStatus.DAI_RU_KU.equals(form.getOperateType())) {
            status = WmsPurchaseOrderSelfEnum.WmsOrderStatus.DAI_RU_KU;
        }

        wmsPurchaseOrderSelf.setWmsOrderStatus(status);
        // 仓库UUID
        checkWmsHorsePresent(form.getWmsHorseId());
        wmsPurchaseOrderSelf.setWmsHorseUUID(form.getWmsHorseId());
        // 库房名称
        wmsPurchaseOrderSelf.setWmsHorseName(wmsWarehouseManage.getSerName());
        // 备注
        wmsPurchaseOrderSelf.setSerMemo(form.getRemark());
        // .....
        return wmsPurchaseOrderSelf;

    }


    /**
     * 合并 OrderSelf 数据
     *
     * @param orderSelf
     * @param form
     * @return
     */
    private WmsPurchaseOrderSelf mereOrderSelfData(WmsPurchaseOrderSelf orderSelf, UpdateForm form) {
        // 备注
        orderSelf.setSerMemo(form.getRemark());
        // 更新修改时间
        orderSelf.setLastModifyTime(LocalDateTime.now());
        // 校验仓库是否存在
        WmsWarehouseManage wmsWarehouseManage = checkWmsHorsePresent(form.getWmsHorseId());
        // 修改仓库id
        orderSelf.setWmsHorseUUID(form.getWmsHorseId());
        // 修改仓库名称
        orderSelf.setWmsHorseName(wmsWarehouseManage.getSerName());

        return orderSelf;
    }

    /**
     * 删除 以前的订单行信息 插入新的
     *
     * @param form
     * @return
     */
    private void mereOrderLineAndInsertData(UpdateForm form) {
        List<WmsPurchaseOrderLine> oldLines = form.getFormLines().stream()
                .filter(item -> item.getUuid() != null)
                .map(item -> {
                    WmsPurchaseOrderLine wmsPurchaseOrderLine = new WmsPurchaseOrderLine();
                    wmsPurchaseOrderLine.setUuid(item.getUuid());
                    return wmsPurchaseOrderLine;
                }).collect(Collectors.toList());
        // 删除旧数据
        Services.wmsPurchaseOrderLine.delete(oldLines);
        // 插入新数据
        List<WmsPurchaseOrderLine> wmsPurchaseOrderLines = buildWmsPurchaseOrderLine(form.getUuid(), form.getFormLines());
        // 插入新数据
        Services.wmsPurchaseOrderLine.saveList(wmsPurchaseOrderLines);
    }

    /**
     * 校验仓库是否存在
     *
     * @param wmsHorseId
     */
    private WmsWarehouseManage checkWmsHorsePresent(UUID wmsHorseId) {
        Optional<WmsWarehouseManage> wmsWarehouseManage = Services.wmsWarehouseManage.single(wmsHorseId);
        if (!wmsWarehouseManage.isPresent()) {
            throw new ServiceErrorException("仓库不存在！");
        }
        return wmsWarehouseManage.get();
    }


}
